package com.nuanshui.heatedloan.dubbo.extension.container;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.container.Container;
import com.alibaba.dubbo.container.spring.SpringContainer;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ResourceUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * 自定义的container实现。用来加载自定义的xml配置文件
 * @Author: Gonzo
 * @Date 2017/3/24下午2:31
 * @since 1.4.2
 */
public class SpringExtendsContainer implements Container {

    private static final Logger logger = LoggerFactory.getLogger(SpringContainer.class);

    public static final String DEFAULT_SPRING_CONFIG = "classpath*:META-INF/spring/*.xml";

    public static final String XMLCONFIG_PREFIX = "META-INF/spring";

    public static final String EVICT_SPRINGXML = "evictSpringxml";//去除的xml

    public static final String INPORT_SPRINGXML = "importSpringxml";//要导入的xml

    public static final String CLASSPATH_PREFIX = "classpath:";

    static ClassPathXmlApplicationContext context;

    public static ClassPathXmlApplicationContext getContext() {
        return context;
    }

    public void start() {
        logger.info("------------------------当前使用自定义的container 进行启动啦-----------------------");
        List<String> configs = getXmlConfig();
        String[] configArray = new String[configs.size()];
        int i = 0;
        logger.info("本次启动选择加载的:");
        for(String config : configs){
            logger.info("[-----" + config +"-----]");
            configArray[i++] = config.trim();
        }
        context = new ClassPathXmlApplicationContext(configArray);
        context.start();
    }

    public void stop() {
        try {
            if (context != null) {
                context.stop();
                context.close();
                context = null;
            }
        } catch (Throwable e) {
            logger.error(e.getMessage(), e);
        }
    }

    
    /**
     * 获取配置的读取xml的
     * @Author: Gonzo
     * @Date 2017/3/24下午4:42
     * @since 1.4.2
     */
    private List<String> getXmlConfig(){

        try{
            BufferedReader reader = null;
            try {
                String [] xmlConfigs = null;
                ClassLoader classLoader = SpringExtendsContainer.class.getClassLoader();
                URL url = classLoader.getResource("META-INF/spring/springLoadXmlConfig.properties");

                if(url != null){
                   reader = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
                    try{
                        String line = null;
                        while((line = reader.readLine()) != null) {
                            String name;
                            int i = line.indexOf('=');
                            if(i > 0){
                                name = line.substring(0, i).trim();
                                line = line.substring(i + 1).trim();

                                if(name.equals(EVICT_SPRINGXML)) {
                                    List<String> xmlConfigList = Lists.newArrayList();
                                    ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
                                    Resource[] resources = resourcePatternResolver.getResources(DEFAULT_SPRING_CONFIG);
                                    for(Resource resource : resources) {
                                        URI uri = resource.getURI();
                                        String path;
                                        if (uri.getScheme().startsWith(ResourceUtils.URL_PROTOCOL_JAR)) {
                                            path = uri.getSchemeSpecificPart();
                                        } else {
                                            path = uri.getPath();
                                        }
                                        int index = path.indexOf(XMLCONFIG_PREFIX);
                                        if(index > 0) {
                                            String fileName = path.substring(index, path.length());
                                            xmlConfigList.add(CLASSPATH_PREFIX + fileName);
                                        }
                                    }

                                    String[] eviteXmls = line.split("[,\\s]");

                                    if(eviteXmls.length > 0){
                                        List<String> eviteXmlList = CollectionUtils.arrayToList(eviteXmls);
                                        Iterator<String> it = xmlConfigList.iterator();

                                        while(it.hasNext()){
                                            String config = it.next();
                                            if(eviteXmlList.contains(config)){
                                                it.remove();
                                            }
                                        }
                                        return xmlConfigList;
                                    }

                                }else if(name.equals(INPORT_SPRINGXML)) {
                                    xmlConfigs  = line.split("[,\\s]");
                                    List<String> eviteXmlList = Lists.newArrayList();
                                    for(String config : xmlConfigs){
                                        if(StringUtils.isNoneEmpty(config)){
                                            eviteXmlList.add(config);
                                        }
                                    }

                                    return eviteXmlList;
                                }
                            }
                        }
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                }
            }catch (Exception e){
                e.printStackTrace();

            }finally {
                if(reader != null){
                    reader.close();
                }

            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return Arrays.asList(DEFAULT_SPRING_CONFIG);
    }

}
